package com.jeesite.modules.pay.totalPay.service;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.SortedMap;
import java.util.TreeMap;

import com.alibaba.fastjson.JSON;
import com.alipay.api.AlipayApiException;
import com.alipay.api.internal.util.AlipaySignature;
import com.jeesite.modules.pay.totalPay.util.DateUtils;
import com.jeesite.modules.pay.totalPay.util.HttpXmlUtils;
import com.jeesite.modules.pay.totalPay.util.StringUtil;
import com.jeesite.modules.pay.totalPay.util.WxSignUtils;

/**
 * @author tz <br>
 *         2017-9-13 12:29:41<br>
 * 
 * @category 原生支付逻辑业务层 <br>
 * 
 *           Properties配置文件：一定要加载<br>
 *           public static String ali_private_key =
 *           LoadProperties.getPayProperty("ali_private_key"); 商户私钥<br>
 *           public static String ali_public_key =
 *           LoadProperties.getPayProperty("ali_public_key"); 商户公钥<br>
 *           public static String ali_alipay_public_key =
 *           LoadProperties.getPayProperty("ali_alipay_public_key");支付宝公钥 <br>
 *           public static String ali_native_app_id =
 *           LoadProperties.getPayProperty("ali_native_app_id"); 支付宝应用id<br>
 *           public static String wx_native_app_id =
 *           LoadProperties.getPayProperty("wx_app_id"); 微信应用id<br>
 *           public static String wx_native_mch_id =
 *           LoadProperties.getPayProperty("wx_mch_id"); 微信商户id<br>
 *           public static String wx_native_key =
 *           LoadProperties.getPayProperty("wx_key"); 微信秘钥<br>
 */
public class NativePayService {

	/**
	 * 加载配置文件
	 */
	/*
	 * public static String ali_private_key =
	 * LoadProperties.getPayProperty("ali_private_key"); // 商户私钥 public static
	 * String ali_public_key = LoadProperties.getPayProperty("ali_public_key");
	 * // 商户公钥 public static String ali_alipay_public_key =
	 * LoadProperties.getPayProperty("ali_alipay_public_key");// 支付宝公钥 public
	 * static String ali_native_app_id =
	 * LoadProperties.getPayProperty("ali_native_app_id"); // 支付宝应用id public
	 * static String wx_native_app_id =
	 * LoadProperties.getPayProperty("wx_app_id"); // 微信应用id public static
	 * String wx_native_mch_id = LoadProperties.getPayProperty("wx_mch_id"); //
	 * 微信商户id public static String wx_native_key =
	 * LoadProperties.getPayProperty("wx_key"); // 微信秘钥
	 */public static String wxPayUrl = "https://api.mch.weixin.qq.com/pay/unifiedorder"; // 微信预付单地址

	/*public static String wxQueryUrl = LoadProperties
			.getPayProperty("wxQueryUrl");*/ // 微信预付单地址
	 public static String wxQueryUrl = "";

	// #支付宝商户id
	public static String ali_native_app_id = "2017082508376863";

	// #支付宝商户秘钥
	public static String ali_private_key = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCOGs9J7eXZHfVwgs4MsyXtDDZ1pSWZ0DKv7jl9WympudGpzwmJaTa1Akthso0+r9Fmjg3z6W2/tkc77mXOvzlMAH9Xc3WicRcSy5Hq2887yshIysKvIf0blbCfiWtFgLhSA0QZ0eeqiev1D3HUBjFui0nIUdoknrNrntAAF6BFJMaZRUH21bD96ND1ZXld6YaQczbq0j181TZg2vPMn2FtiYLqvkkPmEwk+iA2vDPIJfOYXggIBFxPzl2bsG2bpIQ1smD1LUsbP17VRKnFDmmpaMwSmrpDTUecf7jDCm18NiAJS655eY2i85KnuxnTcp7AOoe5ViL3zKm62lJYCN/1AgMBAAECggEAHqjyKIVHnjy0g/307xCIEkkcRu3G2xTsmsDPbpiIuLH65qRg7mDhCNTh5sZbazcL+xCTOhkXMNHnNKsPFDh16EwDLZ8ftlioHcoGRaH/aGssI2h78MVoktcNMJ65ollPa4KA4wFC9qyjWFBowtJDQBKVbL8cTeJf28x8HEj8r24YX+ozSH8jv7vR2AwezToVypnOXTAt+M3fhQ3sEaMNfj7wmBBNkwEQjJ673ksWN5f4a+VhR9DXY1/T/KAaVPpzXtLirWbUuxZG4i2jahSqS0cagmXkO/8rvVFV99udo3BKPxlQ58WeZe1wc1/i4pzmUGxJF5Cqeq+wbNbgR2EaUQKBgQDh1/wa5sFU+6G0O80aIv6UhdywUac/GAm6jcRZevquR93TqZfNG8nZrhpYwLjpuTjTwLSAu7OMLWDyHCAY8iB+85ZVcTYNtEKrTyzqmZkgRly5scmhGmqKtPRNr+tEHEgu1k+OCEI0wTa5DFyrcsBtURmX1AQLzmgNregfjLrKewKBgQChFGAyPScJ+pv1VOXO8qC77qREkhjnfdrCFxA1qjowC7ymzK9TaROv/V5brvPtYuRvEiTWEWagHfOfjyHWtN8LZAh2+scK9tQcc0EkMup0CuNpnZGco0i1SqqSO0kQn+mjk9EJnFT/4zBjHX/Gd0tqCqMLx5jhARbGjP6048HsTwKBgFu6F6DtfDSCB0lmyIUHFZNJUzshzuXnY3wrvEYDlvFWKxie1xLtaGxLNFQ74l67ZgNLT4TBt8kFXUy4c6juHpixYqvNUYD7Z+CgRcP7IqBjM6IQPa57Ri6UFG3BN7LwMbkkPieX3xwCJbG+/Zx8/P7pY5Ww/Pu2l7iGm7LEu9ElAoGAHP9kCedEXeGFrfaooEbBdNOTMtzyKspXVVV9j4ujif6y6Xwzm9pwtt/v2qV2OCfzY6Nqijb7uJtrvi+wMczB0nUhqPmgV3Lz4GNHONMJrfY/1kWNbxtd/XUBm+2cS6feEZqMqSRBkQc/MLigxgO3ydE8ZOR7uxXNGdVMDRhrUrUCgYEAhR6ska5fbsi3Z6MtbIhxRAzKAIheFh9HI0sUYYzqpuaAxsb8ipKPjPgdGi7y5hdayeJ0Ykp/b232hDH10ugjCyDTjyroOUSlB23THfqgZQ1hLnx1axVXMPA9b/cE4/T7mGF2rb0fkVKET9ixf638qRlt3QILitcNGH08K2WyHvg=";

	// #支付宝商户公钥
	public static String ali_public_key = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAjhrPSe3l2R31cILODLMl7Qw2daUlmdAyr+45fVspqbnRqc8JiWk2tQJLYbKNPq/RZo4N8+ltv7ZHO+5lzr85TAB/V3N1onEXEsuR6tvPO8rISMrCryH9G5Wwn4lrRYC4UgNEGdHnqonr9Q9x1AYxbotJyFHaJJ6za57QABegRSTGmUVB9tWw/ejQ9WV5XemGkHM26tI9fNU2YNrzzJ9hbYmC6r5JD5hMJPogNrwzyCXzmF4ICARcT85dm7Btm6SENbJg9S1LGz9e1USpxQ5pqWjMEpq6Q01HnH+4wwptfDYgCUuueXmNovOSp7sZ03KewDqHuVYi98yputpSWAjf9QIDAQAB";
	                                       
	// #支付宝公钥
	// public static String ali_alipay_public_key =
	// "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAjhrPSe3l2R31cILODLMl7Qw2daUlmdAyr+45fVspqbnRqc8JiWk2tQJLYbKNPq/RZo4N8+ltv7ZHO+5lzr85TAB/V3N1onEXEsuR6tvPO8rISMrCryH9G5Wwn4lrRYC4UgNEGdHnqonr9Q9x1AYxbotJyFHaJJ6za57QABegRSTGmUVB9tWw/ejQ9WV5XemGkHM26tI9fNU2YNrzzJ9hbYmC6r5JD5hMJPogNrwzyCXzmF4ICARcT85dm7Btm6SENbJg9S1LGz9e1USpxQ5pqWjMEpq6Q01HnH+4wwptfDYgCUuueXmNovOSp7sZ03KewDqHuVYi98yputpSWAjf9QIDAQAB";
	private static String ali_alipay_public_key = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmDBo5ulbiFr16J+oZk6owNGIdsRW/vkzpI13A3UjPUVj930zCFL1JW+KSnIZ6T9WiUcZMe3TD/F6JuEbtC25qwnLFjbiIN89XSrn7+ghdpy4P7nfY0uxJLdaB7GcGsgtbo3MzamIi0Rb9RjWyH0tNN5tYiyrs5V4xBbpJR1yJbTM4dHZsa7O4aFT0gC83KG6eUrtnZofQKGELqg3yAX57N08gSucRn0I8BXo0PqEel9rpkT7ZGYpBKwGGu1rZhd/NKUnfmyK2KYEXjQfyaJ0hzLuQ5rtqzMGQcRej5UvrI2ITgiDcrt6R3lNnqzEgJQR7jdHEyycp52oZx4LMwGuFQIDAQAB";

	
	
	// #------------------------------微信
/*	// #微信应用id   
	public static String wx_native_app_id = "wx87ac9e91ed2e9c64";//小程序id
	// #微信商户号          
	public static String wx_native_mch_id = "1515232101"; //商户id
	// #微信商户秘钥            
	public static String wx_native_key = "r3iLWuqaf63UmkFEUMSEwpPgUzdqpe2h";//商户秘钥
*/
	// #微信应用id   wxb0283c0ffa73cd90
	public static String wx_native_app_id = "wx59095f22b247d4a6";//小程序id
	// #微信商户号           1521788521 
	public static String wx_native_mch_id = "1321344901"; //商户id
	// #微信商户秘钥           hYxMgLK2QwobUGFFS7h0HUPury86vXww 
	public static String wx_native_key = "sIPWzGje4hb6HPg71Rvm3KIaaLEBmcUd";//商户秘钥
	
	
	
	
	/*// #微信应用id   wx8d8a8682b9a3347f
		public static String wx_native_app_id = "wx8d8a8682b9a3347f";
		// #微信商户号          1493709612
		public static String wx_native_mch_id = "1493709612"; 
		// #微信商户秘钥            8UI7SuWeq33KN18V306XAXE85EZL72Al
		public static String wx_native_key = "8UI7SuWeq33KN18V306XAXE85EZL72Al";*/
		
	/**
	 * 支付宝支付封装参数，签名方式为RSA 对应支付宝工具生成的1024加密方式<br>
	 * 实际传递参数为Map类型，下列参数是put在map中的
	 * 
	 * @param pay_title
	 *            支付标题
	 * @param out_trade_no
	 *            订单号
	 * @param total_fee
	 *            支付金额
	 * @param timeout_express
	 *            超时时间 不设置 默认为10分钟
	 * @param notify_url
	 *            回调地址 例： https://tz.com/pay/notify/
	 * @return code SUCCESS--- msg 生成成功 ||code ERROR ----- msg 失败 <br>
	 *         返回类型为Map<String,String>
	 */
	public static Map<String, String> aliNativePay(Map<String, String> pa) {
		
		Map<String, String> params = new HashMap<String, String>();
		params.put("app_id", ali_native_app_id);
		Map<String, String> biz_content = new HashMap<String, String>();
		biz_content.put("subject", pa.get("pay_title"));
		biz_content.put("out_trade_no", pa.get("out_trade_no"));
		biz_content.put("total_amount",
				(Float.parseFloat(pa.get("total_fee")) / 100) + "");
		biz_content.put("product_code", "QUICK_MSECURITY_PAY");
		biz_content.put("timeout_express", StringUtil.isEmpty(pa
				.get("timeout_express")) ? "10m" : pa.get("timeout_express"));
		params.put("biz_content", JSON.toJSONString(biz_content));
		params.put("charset", "utf-8");
		params.put("format", "JSON");
		params.put("method", "alipay.trade.app.pay");
		params.put("notify_url", pa.get("notify_url"));
		params.put("sign_type", "RSA");
		params.put("timestamp", DateUtils.formatDateTime3(new Date()));
		params.put("version", "1.0");
		StringBuilder sb = new StringBuilder();
		try {
			String sign = AlipaySignature.rsaSign(params, ali_private_key,
					"UTF-8");
			List<String> list = new ArrayList<String>();
			for (Entry<String, String> entry : params.entrySet()) {
				list.add(entry.getKey() + "="
						+ URLEncoder.encode(entry.getValue(), "UTF-8") + "&");
			}
			int size = list.size();
			String[] arrayToSort = list.toArray(new String[size]);
			Arrays.sort(arrayToSort, String.CASE_INSENSITIVE_ORDER);

			for (int i = 0; i < size; i++) {
				sb.append(arrayToSort[i]);
			}
			sb.append("sign=" + URLEncoder.encode(sign, "UTF-8"));
		} catch (AlipayApiException e1) {

			e1.printStackTrace();
		} catch (UnsupportedEncodingException e) {

			e.printStackTrace();
		}
		params.clear();
		System.out.println("sb:" + sb);
		if (sb != null && sb.length() > 0) {
			params.put("code", "SUCCESS");
			params.put("msg", "订单签名成功");
			params.put("data", sb.toString());
			params.put("out_trade_no", pa.get("out_trade_no"));
		} else {
			params.put("code", "ERROE");
			params.put("msg", "生成失败");
		}
		params.put("service", "支付宝支付");
		return params;

	}

	
	/**
	 * 微信原生支付
	 * 
	 * @param pay_title
	 *            支付标题
	 * @param out_trade_no
	 *            订单号
	 * @param total_fee
	 *            支付金额
	 * @param spbill_create_ip
	 *            生成订单的ip地址
	 * @param notify_url
	 *            回调地址 例： https://tz.com/pay/notify/
	 * @return Map 请看详细信息
	 */
	public static Map<String, String> weixinpay(Map<String, String> pa) {
		Map<String, String> result = new HashMap<String, String>();
		// 随机字符
		String nonce_str = StringUtil.getRandomNum(8);

		String body = pa.get("pay_title");

		String total_fee = pa.get("total_fee");
		String spbill_create_ip = pa.get("spbill_create_ip").split(",")[0];// "127.0.0.1";
		String notify_url = pa.get("notify_url");
		System.out.println("notify_url是：" + notify_url);
		// 支付类型
		String trade_type = "APP";

		float timestamp = System.currentTimeMillis() / 1000;
		// 参数：开始生成签名
		SortedMap<Object, Object> parameters = new TreeMap<Object, Object>();
		parameters.clear();
		parameters.put("appid", wx_native_app_id);
		parameters.put("mch_id", wx_native_mch_id);
		parameters.put("nonce_str", nonce_str);
		parameters.put("body", body);
		parameters.put("out_trade_no", pa.get("out_trade_no"));
		parameters.put("total_fee", total_fee);
		parameters.put("notify_url", notify_url);
		parameters.put("trade_type", trade_type);
		parameters.put("spbill_create_ip", spbill_create_ip);
		String sign = WxSignUtils
				.createSign("UTF-8", parameters, wx_native_key);
		System.out.println("签名是：" + sign);
		parameters.put("sign", sign);
		// 构造xml参数
		String xmlInfo = HttpXmlUtils.xmlInfo(parameters);
		String payNo = HttpXmlUtils.httpsRequest(wxPayUrl, xmlInfo);
		System.out.println("请求结果" + payNo);
		Map doXMLParse = null;
		String signStr = "";
		try {
			doXMLParse = HttpXmlUtils.doXMLParse(payNo);
			if ("SUCCESS".equals(doXMLParse.get("return_code"))) {
				SortedMap<Object, Object> againParameters = new TreeMap<Object, Object>();
				againParameters.put("appid", doXMLParse.get("appid"));
				againParameters.put("partnerid", wx_native_mch_id);
				againParameters.put("prepayid", doXMLParse.get("prepay_id"));
				againParameters.put("noncestr", StringUtil.getRandomNum(8));
				againParameters.put("timestamp",
						System.currentTimeMillis() / 1000);
				againParameters.put("package", "Sign=WXPay");
				String sign1 = WxSignUtils.createSign("UTF-8", againParameters,
						wx_native_key);
				againParameters.put("sign", sign1);
				signStr = JSON.toJSONString(againParameters);
				System.out.println("再次签名结果" + signStr);
				result.put("code", "SUCCESS");
				result.put("msg", "签名成功");
				result.put("data", signStr);
				result.put("out_trade_no", pa.get("out_trade_no"));
			} else {
				result.put("code", "ERROR");
				result.put("msg", "签名失败");
			}

		} catch (Exception e) {

			e.printStackTrace();
		}
		result.put("service", "微信支付");
		System.out
				.println("=========================================================");
		return result;

	}

	/**
	 * 微信订单查询
	 * 
	 * @param out_trade_no
	 *            商户订单号
	 * @return
	 * @throws Exception
	 */
	public static Map<String, String> wxNativeQuery(String out_trade_no)
			throws Exception {
		String code = "";
		String msg = "";
		String nonce_str = StringUtil.getRandomNum(8);
		// 参数：开始生成签名
		SortedMap<Object, Object> parameters = new TreeMap<Object, Object>();
		parameters.put("appid", wx_native_app_id);
		parameters.put("mch_id", wx_native_mch_id);
		parameters.put("nonce_str", nonce_str);
		parameters.put("out_trade_no", out_trade_no);
		String sign = WxSignUtils
				.createSign("UTF-8", parameters, wx_native_key);
		System.out.println("签名是：" + sign);
		parameters.put("sign", sign);

		// 构造xml参数
		String xmlInfo = HttpXmlUtils.xmlInfo(parameters);

		String payNo = HttpXmlUtils.httpsRequest(wxQueryUrl, xmlInfo);
		Map doXMLParse = HttpXmlUtils.doXMLParse(payNo);
		if ("SUCCESS".equals(doXMLParse.get("return_code"))) {
			if ("SUCCESS".equals(doXMLParse.get("result_code"))) {
				String trade_state = doXMLParse.get("trade_state") + "";
				if ("SUCCESS".equals(trade_state)) {
					code = trade_state;
					msg = "支付成功";
				} else if ("REFUND".equals(trade_state)) {
					code = trade_state;
					msg = "转入退款";
				} else if ("NOTPAY".equals(trade_state)) {
					code = trade_state;
					msg = "未支付";
				} else if ("CLOSED".equals(trade_state)) {
					code = trade_state;
					msg = "已关闭";
				} else if ("REVOKED".equals(trade_state)) {
					code = trade_state;
					msg = "已撤销";
				} else if ("USERPAYING".equals(trade_state)) {
					code = trade_state;
					msg = "支付中";
				} else if ("PAYERROR".equals(trade_state)) {
					code = trade_state;
					msg = "支付失败(其他原因，如银行返回失败)";
				}
			} else {
				code = "FAIL";
				msg = doXMLParse.get("err_code_des") + ",确认后需重新查询";
			}
		} else {
			code = "ERROE";
			msg = "系统错误-查询失败";
		}
		doXMLParse.put("code", code);
		doXMLParse.put("msg", msg);
		return doXMLParse;
	}

	/**
	 * 微信原生支付
	 * 
	 * @param pay_title
	 *            支付标题
	 * @param out_trade_no
	 *            订单号
	 * @param total_fee
	 *            支付金额
	 * @param spbill_create_ip
	 *            生成订单的ip地址
	 * @param notify_url
	 *            回调地址 例： https://tz.com/pay/notify/
	 * @return Map 请看详细信息
	 */
	public static Map<String, String> weixinH5pay(Map<String, String> pa) {
		Map<String, String> result = new HashMap<String, String>();
		// 随机字符
		String nonce_str = StringUtil.getRandomNum(8).trim();

		String body = pa.get("pay_title").trim();

		String total_fee = pa.get("total_fee").trim();
		String openid = pa.get("openid").trim();
		
		String spbill_create_ip = pa.get("spbill_create_ip").split(",")[0].trim();
		
		String notify_url = pa.get("notify_url").trim();
		
		// 支付类型
		String trade_type = "JSAPI";// APP JSAPI NATIVE MWEB

		// 参数：开始生成签名
		SortedMap<Object, Object> parameters = new TreeMap<Object, Object>();
		parameters.put("appid", wx_native_app_id.trim());
	
		parameters.put("mch_id", wx_native_mch_id.trim());
		parameters.put("nonce_str", nonce_str.trim());
		parameters.put("body", body.trim());
		parameters.put("out_trade_no", pa.get("out_trade_no").trim());
		parameters.put("total_fee", total_fee.trim());
		parameters.put("spbill_create_ip", spbill_create_ip.trim());
		parameters.put("openid", openid.trim());
		parameters.put("notify_url", notify_url.trim());
		parameters.put("trade_type", trade_type.trim());
	//	parameters.put("scene_info","{\"h5_info\": {\"type\":\"Wap\",\"wap_url\": \"https://ylkt.xuanmingkeji.com\",\"wap_name\": \"tzpay\"}}");// 域名需要在微信商户下配置
		String sign = WxSignUtils
				.createSign("UTF-8", parameters, wx_native_key);
		System.out.println("签名是：" + sign);
		parameters.put("sign", sign);
		// 构造xml参数
		String xmlInfo = HttpXmlUtils.xmlInfo(parameters);
		System.out.println(xmlInfo);
		String payNo = HttpXmlUtils.httpsRequest(wxPayUrl, xmlInfo);
		System.out.println("请求结果" + payNo);
		Map doXMLParse = null;
		try {
			doXMLParse = HttpXmlUtils.doXMLParse(payNo);
			if ("SUCCESS".equals(doXMLParse.get("return_code"))) {
				if ("SUCCESS".equals(doXMLParse.get("result_code"))) {
					result.put("code", "SUCCESS");
					result.put("msg", "成功");
					//result.put("data", JSON.toJSONString(doXMLParse));

					/*result.put("mweb_url", doXMLParse.get("mweb_url")
							.toString());*/
					
					String timeStamp=String.valueOf(System.currentTimeMillis()).trim();
					
					SortedMap<Object, Object> map = new TreeMap<Object, Object>();
					
					
					String nonceStr=doXMLParse.get("nonce_str")
							.toString().trim();
					String prepay_id= "prepay_id="+doXMLParse.get("prepay_id")
							.toString().trim();
					String appid=doXMLParse.get("appid")
							.toString().trim();
					
					map.put("nonceStr", nonceStr);
					map.put("package",prepay_id);
					map.put("timeStamp", timeStamp);
					
					map.put("signType","MD5");
					
					map.put("appId",appid);
					result.put("appId",appid);
					
					result.put("signType", "MD5");
					
					result.put("orderno", pa.get("out_trade_no").trim());
					
					result.put("nonceStr", nonceStr);					
					
					result.put("package", prepay_id);
					result.put("timeStamp", timeStamp);
										
					result.put("paySign", WxSignUtils.createSign("UTF-8", map, wx_native_key)
							.toString().trim());
					//result.put("out_trade_no", pa.get("out_trade_no"));
				} else {
					result.put("code", "ERROR");
					result.put("msg", "失败");
				}
				
			} else {
				result.put("code", "ERROR");
				result.put("msg", "失败");
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		//result.put("service", "微信支付");
		
		return result;

	}

}
